<?php
/*
 * class curlADP
*/

class curlADP {
	var $url = NULL;
	var $res = NULL;
	var $gets = NULL; //get query string
	var $_option = array();
	var $_timeout = 0;
	var $_conn_timeout = 0;
	static $boundary = '';
	
	function curlADP() {
	}
	
	function adp_init($conf = NULL) {
		if (isset($conf['timeout'])) {
			$this->_timeout = $conf['timeout'];
		}
		if (isset($conf['conn_timeout'])) {
			$this->_conn_timeout = $conf['conn_timeout'];
		}
	}
	
	function init($url) {
		$this->url = $url;
		$this->res = curl_init($this->url);
		curl_setopt($this->res, CURLOPT_CONNECTTIMEOUT, $this->_timeout);
		curl_setopt($this->res, CURLOPT_TIMEOUT, $this->_timeout);
		self::$boundary = uniqid('------------------');
	}
	
	function set($args, $multi = FALSE, $fileKeyArr = array(
		'pic',
		'image',
		'img'
	)) {
		if ($multi) {
			$this->set(array(
				'head' => array(
					'Content-Type' => 'multipart/form-data; boundary=' . self::$boundary,
					'Expect' => ' '
				)
			));
		}
		//$args=array('get','post','head');
		if (isset($args['get'])) {
			$this->gets = $this->http_build_query($args['get']);
			curl_setopt($this->res, CURLOPT_URL, $this->url . '?' . $this->gets);
		}
		if (isset($args['post'])) {
			$this->_option[CURLOPT_POSTFIELDS] = $this->http_build_query($args['post'], $multi, $fileKeyArr /*, $enc_type =PHP_QUERY_RFC3986*/ /*,NULL,NULL,PHP_QUERY_RFC3986*/);
		}
		if (isset($args['head'])) {
			$ret = array();
			foreach ($args['head'] as $k => $v) {
				$ret[] = $k . ':' . $v;
			}
			if (isset($this->_option[CURLOPT_HTTPHEADER]) && is_array($this->_option[CURLOPT_HTTPHEADER])) {
				$this->_option[CURLOPT_HTTPHEADER] = array_merge($this->_option[CURLOPT_HTTPHEADER], $ret);
			}
			else {
				$this->_option[CURLOPT_HTTPHEADER] = $ret;
			}
		}
		if (isset($args['cookie'])) {
			//curl_setopt($this->res, CURLOPT_COOKIEFILE, "cookiefile");
			
			//curl_setopt($this->res, CURLOPT_COOKIEJAR, "cookiefile"); # SAME cookiefile
			if (is_array($args['cookie'])) {
				$ret = array();
				foreach ($args['cookie'] as $k => $v) {
					$ret[] = $k . '=' . $v;
				}
				$this->_option[CURLOPT_COOKIE] = implode(';', $ret);
			}
			else {
				$ret = $args['cookie'];
				if (isset($this->_option[CURLOPT_COOKIE])) {
					$this->_option[CURLOPT_COOKIE].= $ret;
				}
				else {
					$this->_option[CURLOPT_COOKIE] = $ret;
				}
			}
		}
	}
	
	function upload($fileName, $postName) {
		if (isset($this->_option[CURLOPT_HTTPHEADER]) && is_array($this->_option[CURLOPT_HTTPHEADER])) {
			$this->_option[CURLOPT_HTTPHEADER] = array_merge($this->_option[CURLOPT_HTTPHEADER], array(
				'Content-Type' => 'multipart/form-data'
			));
		}
		else {
			$this->_option[CURLOPT_HTTPHEADER] = array(
				'Content-Type' => 'multipart/form-data'
			);
		}
		$file = fopen($fileName, 'r');
		$size = filesize($fileName);
		$this->set(array(
			'post' => array(
				$postName => '@' . $fileName
			)
		));
		curl_setopt($this->res, CURLOPT_INFILE, $file);
		curl_setopt($this->res, CURLOPT_INFILESIZE, $size);
		curl_setopt($this->res, CURLOPT_FOLLOWLOCATION, FALSE);
		return $this->request('post');
	}
	//urlencode 交给外部处理
	
	function http_build_query($params, $multi = FALSE, $fileKeyArr = array(
		'pic',
		'image',
		'img'
	)) {
		if ($multi) {
			$boundary = self::$boundary;
			$MPboundary = '--' . $boundary;
			$endMPboundary = $MPboundary . '--';
			$multipartbody = '';
			foreach ($params as $parameter => $value) {
				//if( $parameter == 'pic' && $value{0} == '@' )
				if (in_array($parameter, $fileKeyArr) && $value{0} == '@') {
					$url = ltrim($value, '@');
					$content = file_get_contents($url);
					$filename = reset(explode('?', basename($url)));
					$mime = F('get_image_mime', $url);
					$multipartbody.= $MPboundary . "\r\n";
					$multipartbody.= 'Content-Disposition: form-data; name="' . $parameter . '"; filename="' . $filename . '"' . "\r\n";
					$multipartbody.= 'Content-Type: ' . $mime . "\r\n\r\n";
					$multipartbody.= $content . "\r\n";
				}
				else {
					$multipartbody.= $MPboundary . "\r\n";
					$multipartbody.= 'content-disposition: form-data; name="' . $parameter . "\"\r\n\r\n";
					$multipartbody.= $value . "\r\n";
				}
			}
			$multipartbody.= $endMPboundary;
			return $multipartbody;
		}
		else {
			$ret = array();
			foreach ($params as $k => $v) {
				$ret[] = $k . '=' . $v;
			}
			$ret = implode('&', $ret);
			return $ret;
		}
	}
	
	function request($method = 'get', $withInfo = TRUE, $withHead = FALSE) {
		//type=get,post,head
		switch ($method) {
			case 'post':
			case 'file':
				$this->_option[CURLOPT_POST] = TRUE;
				$this->_option[CURLOPT_CUSTOMREQUEST] = 'POST';
			break;
			case 'head':
				$this->_option[CURLOPT_POST] = FALSE;
				$this->_option[CURLOPT_CUSTOMREQUEST] = 'HEAD';
			break;
			case 'get':
				$this->_option[CURLOPT_POST] = FALSE;
				$this->_option[CURLOPT_CUSTOMREQUEST] = 'GET';
			break;
			case 'put':
				$this->_option[CURLOPT_POST] = FALSE;
				$this->_option[CURLOPT_CUSTOMREQUEST] = 'PUT';
			break;
			case 'delete':
				$this->_option[CURLOPT_POST] = FALSE;
				$this->_option[CURLOPT_CUSTOMREQUEST] = 'DELETE';
			break;
			default:
				$this->_option[CURLOPT_POST] = FALSE;
				$this->_option[CURLOPT_CUSTOMREQUEST] = 'GET';
		}
		curl_setopt($this->res, CURLOPT_RETURNTRANSFER, TRUE);
		//
		if ($withHead) {
			curl_setopt($this->res, CURLINFO_HEADER_OUT, TRUE);
			curl_setopt($this->res, CURLOPT_HEADER, TRUE); //输出内容包含头信息
			
		}
		//curl_setopt($this->res, CURLOPT_VERBOSE, FALSE);
		
		//curl_setopt($this->res, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
		curl_setopt_array($this->res, $this->_option);
		$ret = curl_exec($this->res);
		if ($withHead) {
			list($header, $body) = explode("\r\n\r\n", $ret, 2);
			$rr = preg_split("/\r\n/", $header);
			$headerArr = array();
			foreach ($rr as $r) {
				$t = preg_split("/:/", $r, 2);
				if (count($t) == 2) $headerArr[$t[0]] = $t[1];
			}
		}
		else {
			$body = $ret;
			$headerArr = array();
		}
		if (curl_errno($this->res) == 0) {
			if ($withInfo) {
				$rst = array(
					'errno' => 0,
					'data' => $body,
					'info' => array(
						'http_code' => curl_getinfo($this->res, CURLINFO_HTTP_CODE) ,
						'filetime' => curl_getinfo($this->res, CURLINFO_FILETIME) ,
						'total_time' => curl_getinfo($this->res, CURLINFO_TOTAL_TIME) ,
						'head' => $headerArr,
						'size_upload' => curl_getinfo($this->res, CURLINFO_SIZE_UPLOAD) ,
						'head_size' => curl_getinfo($this->res, CURLINFO_HEADER_SIZE)
					)
				);
			}
			else {
				$rst = array(
					'data' => $ret
				);
			}
		}
		else {
			$rst = array(
				'errno' => curl_errno($this->res) ,
				'msg' => curl_error($this->res)
			);
		}
		curl_close($this->res);
		return $rst;
	}
}
?>